feat: add VirtualKeypadStandaloneScope to restrict standalone keyboard to a widget subtree#5
Conversation
Co-authored-by: Masum-MSNR <70331283+Masum-MSNR@users.noreply.github.com>
|
@copilot workflow failed. Check our existing code and make sure you follow contributing guidelines. |
Co-authored-by: Masum-MSNR <70331283+Masum-MSNR@users.noreply.github.com>
Co-authored-by: Masum-MSNR <70331283+Masum-MSNR@users.noreply.github.com>
The CI was failing because Applied
Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
|
@copilot workflow fails please check what you are missing. |
Co-authored-by: Masum-MSNR <70331283+Masum-MSNR@users.noreply.github.com>
|
Run dart format --output=none --set-exit-if-changed . still failing |
Co-authored-by: Masum-MSNR <70331283+Masum-MSNR@users.noreply.github.com>
Fixed in cb8afa6. The previous attempt used Dart 3.7.0 which is an older SDK. The CI uses Flutter Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
|
Run dart format --output=none --set-exit-if-changed . you are not doing properly. check the workflow which is testing and analyzing. then make necessary change. as format fails everytime. something you are not doing properly. if test fails it will not merge. |
Co-authored-by: Masum-MSNR <70331283+Masum-MSNR@users.noreply.github.com>
Fixed in da8590e. Formatted with Dart 3.11.0 using package configs (matching Flutter stable’s language version). Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
There was a problem hiding this comment.
Pull request overview
Adds a new standalone “scope” widget to constrain VirtualKeypad(standalone: true) visibility/behavior to a specific widget subtree, addressing the need to ignore focused inputs outside that subtree (e.g., Widgetbook-style multi-preview setups). The PR also includes formatting-only changes across library, tests, and examples to align with CI Dart formatting.
Changes:
- Introduce
VirtualKeypadStandaloneScopeand export it as part of the public package API. - Update standalone-mode keyboard logic to only show (and to auto-hide) when focus is within the same standalone scope.
- Apply
dart format-driven formatting updates across tests, library code, layouts, and examples.
Reviewed changes
Copilot reviewed 21 out of 22 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| test/virtual_keypad_test.dart | Formatting updates + adds widget tests for VirtualKeypadStandaloneScope.maybeOf() lookup behavior. |
| lib/virtual_keypad.dart | Exports standalone_scope.dart and updates package-level docs list. |
| lib/src/widgets/text_field.dart | Formatting-only changes in context menu / bring-into-view logic. |
| lib/src/widgets/keyboard.dart | Implements scope-aware show/hide behavior for standalone mode. |
| lib/src/standalone_scope.dart | Adds VirtualKeypadStandaloneScope widget and maybeOf() ancestor lookup. |
| lib/src/standalone_input_control.dart | Formatting-only changes. |
| lib/src/scope.dart | Formatting-only changes. |
| lib/src/models.dart | Formatting-only changes. |
| lib/src/layouts/languages/french.dart | Formatting-only changes for layout lists. |
| lib/src/layouts/languages/bengali.dart | Formatting-only changes for action key declarations. |
| example/pubspec.lock | Updates example lockfile version for the path dependency. |
| example/lib/screens/standalone_example.dart | Formatting-only changes. |
| example/lib/screens/pin_pad_example.dart | Formatting-only changes. |
| example/lib/screens/password_entry_example.dart | Formatting-only changes. |
| example/lib/screens/numeric_input_example.dart | Formatting-only changes. |
| example/lib/screens/multiline_text_example.dart | Formatting-only changes. |
| example/lib/screens/multi_field_example.dart | Formatting-only changes. |
| example/lib/screens/language_switching_example.dart | Formatting-only changes. |
| example/lib/screens/email_url_example.dart | Formatting-only changes. |
| example/lib/screens/custom_theme_example.dart | Formatting-only changes. |
| example/lib/screens/auto_hide_keyboard_example.dart | Formatting-only changes. |
| example/lib/main.dart | Formatting-only changes. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // If wrapped in a scope, hide when focus moves outside that scope | ||
| final myScope = VirtualKeypadStandaloneScope.maybeOf(context); | ||
| if (myScope != null && _standaloneVisible) { | ||
| final focusedScope = VirtualKeypadStandaloneScope.maybeOf(focus.context!); | ||
| if (focusedScope != myScope) { | ||
| setState(() => _standaloneVisible = false); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /// Called when the [StandaloneInputControl] requests the keyboard to show. | ||
| /// | ||
| /// If the keyboard is wrapped in a [VirtualKeypadStandaloneScope], the | ||
| /// focused text field must be within the same scope for the keyboard to | ||
| /// appear. This prevents the keyboard from responding to text fields that | ||
| /// belong to a different part of the widget tree. | ||
| void _onStandaloneShow() { | ||
| if (!mounted) return; | ||
|
|
||
| // If this keyboard is inside a VirtualKeypadStandaloneScope, only show | ||
| // when the focused widget is in the same scope. | ||
| final myScope = VirtualKeypadStandaloneScope.maybeOf(context); | ||
| if (myScope != null) { | ||
| final focusedContext = FocusManager.instance.primaryFocus?.context; | ||
| final focusedScope = focusedContext != null | ||
| ? VirtualKeypadStandaloneScope.maybeOf(focusedContext) | ||
| : null; | ||
| if (focusedScope != myScope) { | ||
| // The focused field is outside our scope – hide the keyboard. | ||
| if (_standaloneVisible) setState(() => _standaloneVisible = false); | ||
| return; | ||
| } | ||
| } | ||
|
|
||
| setState(() => _standaloneVisible = true); | ||
| _onStandaloneFieldChanged(); | ||
| } |
There was a problem hiding this comment.
The new scope-based standalone behavior is only unit-tested for maybeOf() lookups, but there’s no widget-level test asserting the intended user-facing behavior (e.g., keyboard shows only when the focused field is within the same VirtualKeypadStandaloneScope, and hides when focus moves to a different scope). Adding a testWidgets that builds two scopes with separate TextFields and a standalone VirtualKeypad would help prevent regressions.
| final Widget child; | ||
|
|
||
| /// Returns the nearest [VirtualKeypadStandaloneScopeState] ancestor, or | ||
| /// null if there is none. |
There was a problem hiding this comment.
VirtualKeypadStandaloneScope exposes a maybeOf() lookup, while the existing VirtualKeypadScope uses of() (which already returns nullable). For API consistency within this package, consider renaming maybeOf to of, or adding an of alias that forwards to maybeOf so consumers have a consistent discovery pattern across scope widgets.
| /// null if there is none. | |
| /// null if there is none. | |
| static VirtualKeypadStandaloneScopeState? of(BuildContext context) { | |
| return maybeOf(context); | |
| } | |
| /// Returns the nearest [VirtualKeypadStandaloneScopeState] ancestor, or | |
| /// null if there is none. |
dart format --output=none --set-exit-if-changed .Original prompt
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.